// 初始栈
const stack = []

// 入栈
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)

// 访问栈顶元素
const peek = stack[stack.length - 1]

// 元素出栈
const pop = stack.pop()

// 栈的长度
const size = stack.length

// 栈是否为空
const empty = stack.length === 0


// 节点类
class Node {
    val;
    next;
    constructor(val, next) {
        this.val = (val === undefined ? null : val)
        this.next = (next === undefined ? null : next)
    }
}

// 使用链表模拟栈
class LinkedListStack {
    #stackPeek
    #stackSize = 0
    constructor() {
        this.#stackPeek = null
    }

    // 获取栈的长度
    size() {
        return this.#stackSize
    }

    // 入栈
    push(num) {
        const node = new Node(num)
        // 将原本的头节点赋值给新节点的 next
        node.next = this.#stackPeek
        // 新节点赋值给老头节点更新头节点
        this.#stackPeek = node
        // 更新长度
        this.#stackSize++
    }

    // 出栈
    pop() {
        // 获取栈顶元素
        const num = this.peek()
        // 获取当前头节点的 next 节点， 赋值给 #stackPeek 更新头节点
        this.#stackPeek = this.#stackPeek.next
        // 更新长度
        this.#stackSize--
        // 返回元素
        return num

    }

    // 访问栈顶元素
    peek() {
        if(!this.#stackPeek) throw new Error('栈为空')
        return this.#stackPeek.val
    }

    // 打印链表
    toArray() {
        let node = this.#stackPeek
        let arr = new Array(this.size)
        for(let i = 0; i < arr.length; i++) {
            arr[i] = node.val
            node = node.next
        }
        return arr
    }
}

//基于数组实现栈
class ArrayStack {
    #stack;
    constructor() {
        this.#stack = []
    }

    // 获取栈的长度
    get size() {
        return this.#stack.length
    }

    isEmpty() {
        return this.size === 0
    }

    // 入栈
    push(num) {
        this.#stack.push(num)
    }

    // 出栈
    pop() {
        if(this.isEmpty()) throw new Error('栈为空')
        return this.#stack.pop()
    }

    // 访问栈顶元素
    peek() {
        if(this.isEmpty()) throw new Error('栈为空')
        return this.#stack[this.#stack.length - 1]
    }

    // 
    toArray() {
        return this.#stack
    }
}